﻿namespace Standards.Services.Services
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using Standards.Contracts;
    using Standards.Model.Models;

    public class PermissionsService : IPermissionsService
    {
        private readonly IStandardsUnitOfWorkFactory unitOfWorkFactory;

        public PermissionsService(IStandardsUnitOfWorkFactory unitOfWorkFactory)
        {
            this.unitOfWorkFactory = unitOfWorkFactory;
        }

        public bool HasPermission(string userId, Permission permission)
        {
            var userPermissions = this.GetPermissionsForUser(userId);
            return userPermissions.Any(p => p == permission);
        }

        public bool HasAnyPermission(string userId, IEnumerable<Permission> permissions)
        {
            throw new System.NotImplementedException();
        }

        public bool HasAllPermissions(string userId, IEnumerable<Permission> permissions)
        {
            throw new System.NotImplementedException();
        }

        public IEnumerable<Permission> GetPermissionsForUser(string userId)
        {
            // Get the collection of permissions for the current user            
            using (var unitOfWork = this.unitOfWorkFactory.Create())
            {
                var user = unitOfWork.Users.GetAll(u => u.Roles).FirstOrDefault(u => u.Name == userId);
                if (user == null)
                {
                    return Enumerable.Empty<Permission>();
                }

                // Administrators have all permissions
                if (user.IsAdmin)
                {
                    return GetAvailablePermissions();
                }

                var allPermissions = user.Roles.SelectMany(r => r.Permissions).Distinct();
                return allPermissions.Select(p => p.Permission);
            }
        }

        public IEnumerable<Permission> GetAvailablePermissions()
        {
            var permissions = Enum.GetValues(typeof(Permission));

            // Skip the 'None' value
            return permissions.Cast<Permission>().Skip(1);
        }
    }
}